{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## answer_search.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from py2neo import Graph\n",
    "\n",
    "class AnswerSearcher:\n",
    "    def __init__(self):\n",
    "        # self.g = Graph(\"http://localhost:7474\", username=\"neo4j\", password=\"123456\")\n",
    "        self.g = Graph(\"http://localhost:7474\", auth=(\"neo4j\", \"123456\"))\n",
    "        self.num_limit = 20\n",
    "\n",
    "    '''执行cypher查询，并返回相应结果'''\n",
    "    def search_main(self, sqls):\n",
    "        final_answers = []\n",
    "        for sql_ in sqls:\n",
    "            question_type = sql_['question_type']\n",
    "            queries = sql_['sql']\n",
    "            answers = []\n",
    "            for query in queries:\n",
    "                ress = self.g.run(query).data()\n",
    "                answers += ress\n",
    "            final_answer = self.answer_prettify(question_type, answers)\n",
    "            if final_answer:\n",
    "                final_answers.append(final_answer)\n",
    "        return final_answers\n",
    "\n",
    "    '''根据对应的qustion_type，调用相应的回复模板'''\n",
    "    def answer_prettify(self, question_type, answers):\n",
    "        final_answer = []\n",
    "        if not answers:\n",
    "            return ''\n",
    "        if question_type == 'disease_symptom':\n",
    "            desc = [i['n.name'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}的症状包括：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'symptom_disease':\n",
    "            desc = [i['m.name'] for i in answers]\n",
    "            subject = answers[0]['n.name']\n",
    "            final_answer = '症状{0}可能染上的疾病有：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_cause':\n",
    "            desc = [i['m.cause'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}可能的成因有：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_prevent':\n",
    "            desc = [i['m.prevent'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}的预防措施包括：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_lasttime':\n",
    "            desc = [i['m.cure_lasttime'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}治疗可能持续的周期为：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_cureway':\n",
    "            desc = [';'.join(i['m.cure_way']) for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}可以尝试如下治疗：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_cureprob':\n",
    "            desc = [i['m.cured_prob'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}治愈的概率为（仅供参考）：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_easyget':\n",
    "            desc = [i['m.easy_get'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "\n",
    "            final_answer = '{0}的易感人群包括：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_desc':\n",
    "            desc = [i['m.desc'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0},熟悉一下：{1}'.format(subject,  '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_acompany':\n",
    "            desc1 = [i['n.name'] for i in answers]\n",
    "            desc2 = [i['m.name'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            desc = [i for i in desc1 + desc2 if i != subject]\n",
    "            final_answer = '{0}的症状包括：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_not_food':\n",
    "            desc = [i['n.name'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}忌食的食物包括有：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_do_food':\n",
    "            do_desc = [i['n.name'] for i in answers if i['r.name'] == '宜吃']\n",
    "            recommand_desc = [i['n.name'] for i in answers if i['r.name'] == '推荐食谱']\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}宜食的食物包括有：{1}\\n推荐食谱包括有：{2}'.format(subject, ';'.join(list(set(do_desc))[:self.num_limit]), ';'.join(list(set(recommand_desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'food_not_disease':\n",
    "            desc = [i['m.name'] for i in answers]\n",
    "            subject = answers[0]['n.name']\n",
    "            final_answer = '患有{0}的人最好不要吃{1}'.format('；'.join(list(set(desc))[:self.num_limit]), subject)\n",
    "\n",
    "        elif question_type == 'food_do_disease':\n",
    "            desc = [i['m.name'] for i in answers]\n",
    "            subject = answers[0]['n.name']\n",
    "            final_answer = '患有{0}的人建议多试试{1}'.format('；'.join(list(set(desc))[:self.num_limit]), subject)\n",
    "\n",
    "        elif question_type == 'disease_drug':\n",
    "            desc = [i['n.name'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}通常的使用的药品包括：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'drug_disease':\n",
    "            desc = [i['m.name'] for i in answers]\n",
    "            subject = answers[0]['n.name']\n",
    "            final_answer = '{0}主治的疾病有{1},可以试试'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'disease_check':\n",
    "            desc = [i['n.name'] for i in answers]\n",
    "            subject = answers[0]['m.name']\n",
    "            final_answer = '{0}通常可以通过以下方式检查出来：{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        elif question_type == 'check_disease':\n",
    "            desc = [i['m.name'] for i in answers]\n",
    "            subject = answers[0]['n.name']\n",
    "            final_answer = '通常可以通过{0}检查出来的疾病有{1}'.format(subject, '；'.join(list(set(desc))[:self.num_limit]))\n",
    "\n",
    "        return final_answer\n",
    "\n",
    "searcher = AnswerSearcher()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question_parser.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class QuestionPaser:\n",
    "\n",
    "    '''构建实体节点'''\n",
    "    def build_entitydict(self, args):\n",
    "        entity_dict = {}\n",
    "        for arg, types in args.items():\n",
    "            for type in types:\n",
    "                if type not in entity_dict:\n",
    "                    entity_dict[type] = [arg]\n",
    "                else:\n",
    "                    entity_dict[type].append(arg)\n",
    "\n",
    "        return entity_dict\n",
    "\n",
    "    '''解析主函数'''\n",
    "    def parser_main(self, res_classify):\n",
    "        args = res_classify['args']\n",
    "        entity_dict = self.build_entitydict(args)\n",
    "        question_types = res_classify['question_types']\n",
    "        sqls = []\n",
    "        for question_type in question_types:\n",
    "            sql_ = {}\n",
    "            sql_['question_type'] = question_type\n",
    "            sql = []\n",
    "            if question_type == 'disease_symptom':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'symptom_disease':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('symptom'))\n",
    "\n",
    "            elif question_type == 'disease_cause':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_acompany':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_not_food':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_do_food':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'food_not_disease':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('food'))\n",
    "\n",
    "            elif question_type == 'food_do_disease':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('food'))\n",
    "\n",
    "            elif question_type == 'disease_drug':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'drug_disease':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('drug'))\n",
    "\n",
    "            elif question_type == 'disease_check':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'check_disease':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('check'))\n",
    "\n",
    "            elif question_type == 'disease_prevent':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_lasttime':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_cureway':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_cureprob':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_easyget':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            elif question_type == 'disease_desc':\n",
    "                sql = self.sql_transfer(question_type, entity_dict.get('disease'))\n",
    "\n",
    "            if sql:\n",
    "                sql_['sql'] = sql\n",
    "\n",
    "                sqls.append(sql_)\n",
    "\n",
    "        return sqls\n",
    "\n",
    "    '''针对不同的问题，分开进行处理'''\n",
    "    def sql_transfer(self, question_type, entities):\n",
    "        if not entities:\n",
    "            return []\n",
    "\n",
    "        # 查询语句\n",
    "        sql = []\n",
    "        # 查询疾病的原因\n",
    "        if question_type == 'disease_cause':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.cause\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的防御措施\n",
    "        elif question_type == 'disease_prevent':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.prevent\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的持续时间\n",
    "        elif question_type == 'disease_lasttime':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.cure_lasttime\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的治愈概率\n",
    "        elif question_type == 'disease_cureprob':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.cured_prob\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的治疗方式\n",
    "        elif question_type == 'disease_cureway':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.cure_way\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的易发人群\n",
    "        elif question_type == 'disease_easyget':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.easy_get\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的相关介绍\n",
    "        elif question_type == 'disease_desc':\n",
    "            sql = [\"MATCH (m:Disease) where m.name = '{0}' return m.name, m.desc\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病有哪些症状\n",
    "        elif question_type == 'disease_symptom':\n",
    "            sql = [\"MATCH (m:Disease)-[r:has_symptom]->(n:Symptom) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "\n",
    "        # 查询症状会导致哪些疾病\n",
    "        elif question_type == 'symptom_disease':\n",
    "            sql = [\"MATCH (m:Disease)-[r:has_symptom]->(n:Symptom) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病的并发症\n",
    "        elif question_type == 'disease_acompany':\n",
    "            sql1 = [\"MATCH (m:Disease)-[r:acompany_with]->(n:Disease) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql2 = [\"MATCH (m:Disease)-[r:acompany_with]->(n:Disease) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql = sql1 + sql2\n",
    "        # 查询疾病的忌口\n",
    "        elif question_type == 'disease_not_food':\n",
    "            sql = [\"MATCH (m:Disease)-[r:no_eat]->(n:Food) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "\n",
    "        # 查询疾病建议吃的东西\n",
    "        elif question_type == 'disease_do_food':\n",
    "            sql1 = [\"MATCH (m:Disease)-[r:do_eat]->(n:Food) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql2 = [\"MATCH (m:Disease)-[r:recommand_eat]->(n:Food) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql = sql1 + sql2\n",
    "\n",
    "        # 已知忌口查疾病\n",
    "        elif question_type == 'food_not_disease':\n",
    "            sql = [\"MATCH (m:Disease)-[r:no_eat]->(n:Food) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "\n",
    "        # 已知推荐查疾病\n",
    "        elif question_type == 'food_do_disease':\n",
    "            sql1 = [\"MATCH (m:Disease)-[r:do_eat]->(n:Food) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql2 = [\"MATCH (m:Disease)-[r:recommand_eat]->(n:Food) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql = sql1 + sql2\n",
    "\n",
    "        # 查询疾病常用药品－药品别名记得扩充\n",
    "        elif question_type == 'disease_drug':\n",
    "            sql1 = [\"MATCH (m:Disease)-[r:common_drug]->(n:Drug) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql2 = [\"MATCH (m:Disease)-[r:recommand_drug]->(n:Drug) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql = sql1 + sql2\n",
    "\n",
    "        # 已知药品查询能够治疗的疾病\n",
    "        elif question_type == 'drug_disease':\n",
    "            sql1 = [\"MATCH (m:Disease)-[r:common_drug]->(n:Drug) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql2 = [\"MATCH (m:Disease)-[r:recommand_drug]->(n:Drug) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "            sql = sql1 + sql2\n",
    "        # 查询疾病应该进行的检查\n",
    "        elif question_type == 'disease_check':\n",
    "            sql = [\"MATCH (m:Disease)-[r:need_check]->(n:Check) where m.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "\n",
    "        # 已知检查查询疾病\n",
    "        elif question_type == 'check_disease':\n",
    "            sql = [\"MATCH (m:Disease)-[r:need_check]->(n:Check) where n.name = '{0}' return m.name, r.name, n.name\".format(i) for i in entities]\n",
    "\n",
    "        return sql"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question_classifier.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import ahocorasick\n",
    "\n",
    "class QuestionClassifier:\n",
    "    def __init__(self):\n",
    "        # cur_dir = '/'.join(os.path.abspath(__file__).split('/')[:-1])\n",
    "        cur_dir = os.getcwd()\n",
    "        #　特征词路径\n",
    "        self.disease_path = os.path.join(cur_dir, 'dict/disease.txt')\n",
    "        self.department_path = os.path.join(cur_dir, 'dict/department.txt')\n",
    "        self.check_path = os.path.join(cur_dir, 'dict/check.txt')\n",
    "        self.drug_path = os.path.join(cur_dir, 'dict/drug.txt')\n",
    "        self.food_path = os.path.join(cur_dir, 'dict/food.txt')\n",
    "        self.producer_path = os.path.join(cur_dir, 'dict/producer.txt')\n",
    "        self.symptom_path = os.path.join(cur_dir, 'dict/symptom.txt')\n",
    "        self.deny_path = os.path.join(cur_dir, 'dict/deny.txt')\n",
    "        \n",
    "        # 加载特征词\n",
    "        self.disease_wds= [i.strip() for i in open(self.disease_path,encoding=\"utf-8\") if i.strip()]#encoding=\"utf-8\"\n",
    "        self.department_wds= [i.strip() for i in open(self.department_path,encoding=\"utf-8\") if i.strip()]\n",
    "        self.check_wds= [i.strip() for i in open(self.check_path,encoding=\"utf-8\") if i.strip()]\n",
    "        self.drug_wds= [i.strip() for i in open(self.drug_path,encoding=\"utf-8\") if i.strip()]\n",
    "        self.food_wds= [i.strip() for i in open(self.food_path,encoding=\"utf-8\") if i.strip()]\n",
    "        self.producer_wds= [i.strip() for i in open(self.producer_path,encoding=\"utf-8\") if i.strip()]\n",
    "        self.symptom_wds= [i.strip() for i in open(self.symptom_path,encoding=\"utf-8\") if i.strip()]\n",
    "        self.region_words = set(self.department_wds + self.disease_wds + self.check_wds + self.drug_wds + self.food_wds + self.producer_wds + self.symptom_wds)\n",
    "        self.deny_words = [i.strip() for i in open(self.deny_path,encoding=\"utf-8\") if i.strip()]\n",
    "        # 构造领域actree\n",
    "        self.region_tree = self.build_actree(list(self.region_words))\n",
    "        # 构建词典\n",
    "        self.wdtype_dict = self.build_wdtype_dict()\n",
    "        # 问句疑问词\n",
    "        self.symptom_qwds = ['症状', '表征', '现象', '症候', '表现']\n",
    "        self.cause_qwds = ['原因', '成因', '为什么', '怎么会', '怎样才', '咋样才', '怎样会', '如何会', '为啥', '为何', '如何才会', '怎么才会', '会导致', '会造成']\n",
    "        self.acompany_qwds = ['并发症', '并发', '一起发生', '一并发生', '一起出现', '一并出现', '一同发生', '一同出现', '伴随发生', '伴随', '共现']\n",
    "        self.food_qwds = ['饮食', '饮用', '吃', '食', '伙食', '膳食', '喝', '菜' ,'忌口', '补品', '保健品', '食谱', '菜谱', '食用', '食物','补品']\n",
    "        self.drug_qwds = ['药', '药品', '用药', '胶囊', '口服液', '炎片']\n",
    "        self.prevent_qwds = ['预防', '防范', '抵制', '抵御', '防止','躲避','逃避','避开','免得','逃开','避开','避掉','躲开','躲掉','绕开',\n",
    "                             '怎样才能不', '怎么才能不', '咋样才能不','咋才能不', '如何才能不',\n",
    "                             '怎样才不', '怎么才不', '咋样才不','咋才不', '如何才不',\n",
    "                             '怎样才可以不', '怎么才可以不', '咋样才可以不', '咋才可以不', '如何可以不',\n",
    "                             '怎样才可不', '怎么才可不', '咋样才可不', '咋才可不', '如何可不']\n",
    "        self.lasttime_qwds = ['周期', '多久', '多长时间', '多少时间', '几天', '几年', '多少天', '多少小时', '几个小时', '多少年']\n",
    "        self.cureway_qwds = ['怎么治疗', '如何医治', '怎么医治', '怎么治', '怎么医', '如何治', '医治方式', '疗法', '咋治', '怎么办', '咋办', '咋治']\n",
    "        self.cureprob_qwds = ['多大概率能治好', '多大几率能治好', '治好希望大么', '几率', '几成', '比例', '可能性', '能治', '可治', '可以治', '可以医']\n",
    "        self.easyget_qwds = ['易感人群', '容易感染', '易发人群', '什么人', '哪些人', '感染', '染上', '得上']\n",
    "        self.check_qwds = ['检查', '检查项目', '查出', '检查', '测出', '试出']\n",
    "        self.belong_qwds = ['属于什么科', '属于', '什么科', '科室']\n",
    "        self.cure_qwds = ['治疗什么', '治啥', '治疗啥', '医治啥', '治愈啥', '主治啥', '主治什么', '有什么用', '有何用', '用处', '用途',\n",
    "                          '有什么好处', '有什么益处', '有何益处', '用来', '用来做啥', '用来作甚', '需要', '要']\n",
    "\n",
    "        print('model init finished ......')\n",
    "\n",
    "        return\n",
    "\n",
    "    '''分类主函数'''\n",
    "    def classify(self, question):\n",
    "        data = {}\n",
    "        medical_dict = self.check_medical(question)\n",
    "        if not medical_dict:\n",
    "            return {}\n",
    "        data['args'] = medical_dict\n",
    "        # 收集问句当中所涉及到的实体类型\n",
    "        types = []\n",
    "        for type_ in medical_dict.values():\n",
    "            types += type_\n",
    "        question_type = 'others'\n",
    "\n",
    "        question_types = []\n",
    "\n",
    "        # 症状\n",
    "        if self.check_words(self.symptom_qwds, question) and ('disease' in types):\n",
    "            question_type = 'disease_symptom'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        if self.check_words(self.symptom_qwds, question) and ('symptom' in types):\n",
    "            question_type = 'symptom_disease'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 原因\n",
    "        if self.check_words(self.cause_qwds, question) and ('disease' in types):\n",
    "            question_type = 'disease_cause'\n",
    "            question_types.append(question_type)\n",
    "        # 并发症\n",
    "        if self.check_words(self.acompany_qwds, question) and ('disease' in types):\n",
    "            question_type = 'disease_acompany'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 推荐食品\n",
    "        if self.check_words(self.food_qwds, question) and 'disease' in types:\n",
    "            deny_status = self.check_words(self.deny_words, question)\n",
    "            if deny_status:\n",
    "                question_type = 'disease_not_food'\n",
    "            else:\n",
    "                question_type = 'disease_do_food'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        #已知食物找疾病\n",
    "        if self.check_words(self.food_qwds+self.cure_qwds, question) and 'food' in types:\n",
    "            deny_status = self.check_words(self.deny_words, question)\n",
    "            if deny_status:\n",
    "                question_type = 'food_not_disease'\n",
    "            else:\n",
    "                question_type = 'food_do_disease'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 推荐药品\n",
    "        if self.check_words(self.drug_qwds, question) and 'disease' in types:\n",
    "            question_type = 'disease_drug'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 药品治啥病\n",
    "        if self.check_words(self.cure_qwds, question) and 'drug' in types:\n",
    "            question_type = 'drug_disease'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 疾病接受检查项目\n",
    "        if self.check_words(self.check_qwds, question) and 'disease' in types:\n",
    "            question_type = 'disease_check'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 已知检查项目查相应疾病\n",
    "        if self.check_words(self.check_qwds+self.cure_qwds, question) and 'check' in types:\n",
    "            question_type = 'check_disease'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        #　症状防御\n",
    "        if self.check_words(self.prevent_qwds, question) and 'disease' in types:\n",
    "            question_type = 'disease_prevent'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 疾病医疗周期\n",
    "        if self.check_words(self.lasttime_qwds, question) and 'disease' in types:\n",
    "            question_type = 'disease_lasttime'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 疾病治疗方式\n",
    "        if self.check_words(self.cureway_qwds, question) and 'disease' in types:\n",
    "            question_type = 'disease_cureway'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 疾病治愈可能性\n",
    "        if self.check_words(self.cureprob_qwds, question) and 'disease' in types:\n",
    "            question_type = 'disease_cureprob'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 疾病易感染人群\n",
    "        if self.check_words(self.easyget_qwds, question) and 'disease' in types :\n",
    "            question_type = 'disease_easyget'\n",
    "            question_types.append(question_type)\n",
    "\n",
    "        # 若没有查到相关的外部查询信息，那么则将该疾病的描述信息返回\n",
    "        if question_types == [] and 'disease' in types:\n",
    "            question_types = ['disease_desc']\n",
    "\n",
    "        # 若没有查到相关的外部查询信息，那么则将该疾病的描述信息返回\n",
    "        if question_types == [] and 'symptom' in types:\n",
    "            question_types = ['symptom_disease']\n",
    "\n",
    "        # 将多个分类结果进行合并处理，组装成一个字典\n",
    "        data['question_types'] = question_types\n",
    "\n",
    "        return data\n",
    "\n",
    "    '''构造词对应的类型'''\n",
    "    def build_wdtype_dict(self):\n",
    "        wd_dict = dict()\n",
    "        for wd in self.region_words:\n",
    "            wd_dict[wd] = []\n",
    "            if wd in self.disease_wds:\n",
    "                wd_dict[wd].append('disease')\n",
    "            if wd in self.department_wds:\n",
    "                wd_dict[wd].append('department')\n",
    "            if wd in self.check_wds:\n",
    "                wd_dict[wd].append('check')\n",
    "            if wd in self.drug_wds:\n",
    "                wd_dict[wd].append('drug')\n",
    "            if wd in self.food_wds:\n",
    "                wd_dict[wd].append('food')\n",
    "            if wd in self.symptom_wds:\n",
    "                wd_dict[wd].append('symptom')\n",
    "            if wd in self.producer_wds:\n",
    "                wd_dict[wd].append('producer')\n",
    "        return wd_dict\n",
    "\n",
    "    '''构造actree，加速过滤'''\n",
    "    def build_actree(self, wordlist):\n",
    "        actree = ahocorasick.Automaton()\n",
    "        for index, word in enumerate(wordlist):\n",
    "            actree.add_word(word, (index, word))\n",
    "        actree.make_automaton()\n",
    "        return actree\n",
    "\n",
    "    '''问句过滤'''\n",
    "    def check_medical(self, question):\n",
    "        region_wds = []\n",
    "        for i in self.region_tree.iter(question):\n",
    "            wd = i[1][1]\n",
    "            region_wds.append(wd)\n",
    "        stop_wds = []\n",
    "        for wd1 in region_wds:\n",
    "            for wd2 in region_wds:\n",
    "                if wd1 in wd2 and wd1 != wd2:\n",
    "                    stop_wds.append(wd1)\n",
    "        final_wds = [i for i in region_wds if i not in stop_wds]\n",
    "        final_dict = {i:self.wdtype_dict.get(i) for i in final_wds}\n",
    "\n",
    "        return final_dict\n",
    "\n",
    "    '''基于特征词进行分类'''\n",
    "    def check_words(self, wds, sent):\n",
    "        for wd in wds:\n",
    "            if wd in sent:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[WinError 2] 系统找不到指定的文件。: 'QAMedicalKG'",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mFileNotFoundError\u001B[0m                         Traceback (most recent call last)",
      "\u001B[1;32mC:\\AppData\\Local\\Temp/ipykernel_27160/3216199056.py\u001B[0m in \u001B[0;36m<module>\u001B[1;34m\u001B[0m\n\u001B[1;32m----> 1\u001B[1;33m \u001B[0mos\u001B[0m\u001B[1;33m.\u001B[0m\u001B[0mchdir\u001B[0m\u001B[1;33m(\u001B[0m\u001B[1;34m'QAMedicalKG'\u001B[0m\u001B[1;33m)\u001B[0m\u001B[1;33m\u001B[0m\u001B[1;33m\u001B[0m\u001B[0m\n\u001B[0m",
      "\u001B[1;31mFileNotFoundError\u001B[0m: [WinError 2] 系统找不到指定的文件。: 'QAMedicalKG'"
     ]
    }
   ],
   "source": [
    "os.chdir('QAMedicalKG')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实例化辅助函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "classifier = QuestionClassifier()\n",
    "\n",
    "parser = QuestionPaser()\n",
    "\n",
    "searcher = AnswerSearcher()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 输入问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "question = '肺气肿的病因'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 从问题中提取实体和关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "res_classify = classifier.classify(question)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "res_classify"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 问题解析-生成Cypher查询语句"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "res_cypher = parser.parser_main(res_classify)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "res_cypher"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 生成回答"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "final_answers = searcher.search_main(res_cypher)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "final_answers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
